home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / muse.c < prev    next >
C/C++ Source or Header  |  1993-01-11  |  38KB  |  1,358 lines

  1. /*    SCCS Id: @(#)muse.c    3.1    93/01/03    */
  2. /* Monster item usage routine.  Copyright (C) 1990 by Ken Arromdee */
  3. /* NetHack may be freely redistributed.  See license for details.  */
  4.  
  5. #include "hack.h"
  6.  
  7. #ifdef MUSE
  8.  
  9. extern int monstr[];
  10.  
  11. boolean m_using = FALSE;
  12.  
  13. /* Let monsters use magic items.  Arbitrary assumptions: Monsters only use
  14.  * scrolls when they can see, monsters know when wands have 0 charges, monsters
  15.  * cannot recognize if items are cursed are not, monsters which are confused
  16.  * don't know not to read scrolls, etc....
  17.  */
  18.  
  19. static int FDECL(precheck, (struct monst *,struct obj *));
  20. static void FDECL(mzapmsg, (struct monst *,struct obj *,BOOLEAN_P));
  21. static void FDECL(mreadmsg, (struct monst *,struct obj *));
  22. static void FDECL(mquaffmsg, (struct monst *,struct obj *));
  23. static int FDECL(mbhitm, (struct monst *,struct obj *));
  24. static void FDECL(mbhit,
  25.     (struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)),
  26.     int FDECL((*),(OBJ_P,OBJ_P)),struct obj *));
  27. static void FDECL(you_aggravate, (struct monst *));
  28.  
  29. static struct musable {
  30.     struct obj *offensive;
  31.     struct obj *defensive;
  32.     struct obj *misc;
  33.     int has_offense, has_defense, has_misc;
  34.     /* =0, no capability; otherwise, different numbers.
  35.      * If it's an object, the object is also set (it's 0 otherwise).
  36.      */
  37. } m;
  38. static int trapx, trapy;
  39. static boolean zap_oseen;
  40.     /* for wands which use mbhitm and are zapped at players.  We usually
  41.      * want an oseen local to the function, but this is impossible since the
  42.      * function mbhitm has to be compatible with the normal zap routines,
  43.      * and those routines don't remember who zapped the wand.
  44.      */
  45.  
  46. /* Any preliminary checks which may result in the monster being unable to use
  47.  * the item.  Returns 0 if nothing happened, 2 if the monster can't do anything
  48.  * (i.e. it teleported) and 1 if it's dead.
  49.  */
  50. static int
  51. precheck(mon, obj)
  52. struct monst *mon;
  53. struct obj *obj;
  54. {
  55.     boolean vis = cansee(mon->mx, mon->my);
  56.  
  57.     if (!obj) return 0;
  58.     if (obj->oclass == POTION_CLASS) {
  59.         coord cc;
  60.         static const char *empty = "The potion turns out to be empty.";
  61.         const char * potion_descr ;
  62.         struct monst *mtmp;
  63.  
  64.         potion_descr = OBJ_DESCR(objects[obj->otyp]);
  65.         if (!strcmp(potion_descr, "milky") && !rn2(13)) {
  66.         if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) return 0;
  67.         mquaffmsg(mon, obj);
  68.         m_useup(mon, obj);
  69.         mtmp = makemon(&mons[PM_GHOST], cc.x, cc.y);
  70.         if (!mtmp) {
  71.             if (vis) pline(empty);
  72.         } else {
  73.             if (vis) {
  74.             pline("As %s opens the bottle, an enormous %s emerges!",
  75.                mon_nam(mon),
  76.                Hallucination ? rndmonnam() : (const char *)"ghost");
  77.             pline("%s is frightened to death, and unable to move.",
  78.                 Monnam(mon));
  79.             }
  80.             mon->mcanmove = 0;
  81.             mon->mfrozen = 3;
  82.         }
  83.         return 2;
  84.         }
  85.         if (!strcmp(potion_descr, "smoky") && !rn2(13)) {
  86.         if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) return 0;
  87.         mquaffmsg(mon, obj);
  88.         m_useup(mon, obj);
  89.         mtmp = makemon(&mons[PM_DJINNI], cc.x, cc.y);
  90.         if (!mtmp) {
  91.             if (vis) pline(empty);
  92.         } else {
  93.             if (vis)
  94.             pline("In a cloud of smoke, %s emerges!",
  95.                             a_monnam(mtmp));
  96.             pline("%s speaks.", vis ? Monnam(mtmp) : "Something");
  97.         /* I suspect few players will be upset that monsters */
  98.         /* can't wish for wands of death here.... */
  99.             if (rn2(2)) {
  100.             verbalize("You freed me!");
  101.             mtmp->mpeaceful = 1;
  102.             set_malign(mtmp);
  103.             } else {
  104.             verbalize("It is about time.");
  105.             if (vis) pline("%s vanishes.", Monnam(mtmp));
  106.             mongone(mtmp);
  107.             }
  108.         }
  109.         return 2;
  110.         }
  111.     }
  112.     if (obj->oclass == WAND_CLASS && obj->cursed && !rn2(100)) {
  113.         int dam = d(obj->spe+2, 6);
  114.  
  115. #ifdef SOUNDS
  116.         if (flags.soundok)
  117. #endif
  118.                 {
  119.         if (vis) pline("%s zaps %s, which suddenly explodes!",
  120.             Monnam(mon), an(xname(obj)));
  121.         else You("hear a zap and an explosion in the distance.");
  122.         }
  123.         m_useup(mon, obj);
  124.         if (mon->mhp <= dam) {
  125.         monkilled(mon, "", AD_RBRE);
  126.         return 1;
  127.         }
  128.         else mon->mhp -= dam;
  129.         m.has_defense = m.has_offense = m.has_misc = 0;
  130.         /* Only one needed to be set to 0 but the others are harmless */
  131.     }
  132.     return 0;
  133. }
  134.  
  135. static void
  136. mzapmsg(mtmp, otmp, self)
  137. struct monst *mtmp;
  138. struct obj *otmp;
  139. boolean self;
  140. {
  141.     if (!cansee(mtmp->mx, mtmp->my)) {
  142. #ifdef SOUNDS
  143.         if (flags.soundok)
  144. #endif
  145.             You("hear a distant zap.");
  146.     } else if (self)
  147.         pline("%s zaps %sself with %s!",
  148.             Monnam(mtmp),
  149.             gender(mtmp)==2 ? "it" : gender(mtmp) ? "her" : "him",
  150.             doname(otmp));
  151.     else {
  152.         pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp)));
  153.         stop_occupation();
  154.     }
  155. }
  156.  
  157. static void
  158. mreadmsg(mtmp, otmp)
  159. struct monst *mtmp;
  160. struct obj *otmp;
  161. {
  162.     boolean vis = (cansee(mtmp->mx, mtmp->my));
  163. #ifdef SOUNDS
  164.     if (flags.soundok)
  165. #endif
  166.         otmp->dknown = 1;
  167.     if (!vis) {
  168. #ifdef SOUNDS
  169.         if (flags.soundok)
  170. #endif
  171.             You("hear %s reading %s.",
  172.             an(Hallucination ? rndmonnam() : mtmp->data->mname),
  173.             singular(otmp, doname));
  174.     } else pline("%s reads %s!", Monnam(mtmp), singular(otmp,doname));
  175.     if (mtmp->mconf
  176. #ifdef SOUNDS
  177.         && (vis || flags.soundok)
  178. #endif
  179.                     )
  180.         pline("Being confused, %s mispronounces the magic words...",
  181.             vis ? mon_nam(mtmp) : gender(mtmp)==2 ? "it" :
  182.             gender(mtmp) ? "he" : "she");
  183. }
  184.  
  185. static void
  186. mquaffmsg(mtmp, otmp)
  187. struct monst *mtmp;
  188. struct obj *otmp;
  189. {
  190.     if (cansee(mtmp->mx, mtmp->my)) {
  191.         otmp->dknown = 1;
  192.         pline("%s drinks %s!", Monnam(mtmp), singular(otmp, doname));
  193.     } else
  194. #ifdef SOUNDS
  195.         if (flags.soundok)
  196. #endif
  197.             You("hear a chugging sound.");
  198. }
  199.  
  200. /* Defines for various types of stuff.  The order in which monsters prefer
  201.  * to use them is determined by the order of the code logic, not the
  202.  * numerical order in which they are defined.
  203.  */
  204. #define MUSE_SCR_TELEPORTATION 1
  205. #define MUSE_WAN_TELEPORTATION_SELF 2
  206. #define MUSE_POT_HEALING 3
  207. #define MUSE_POT_EXTRA_HEALING 4
  208. #define MUSE_WAN_DIGGING 5
  209. #define MUSE_TRAPDOOR 6
  210. #define MUSE_TELEPORT_TRAP 7
  211. #define MUSE_UPSTAIRS 8
  212. #define MUSE_DOWNSTAIRS 9
  213. #define MUSE_WAN_CREATE_MONSTER 10
  214. #define MUSE_SCR_CREATE_MONSTER 11
  215. #define MUSE_UP_LADDER 12
  216. #define MUSE_DN_LADDER 13
  217. #define MUSE_SSTAIRS 14
  218. #define MUSE_WAN_TELEPORTATION 15
  219. #ifdef ARMY
  220. # define MUSE_BUGLE 16
  221. #endif
  222. /*
  223. #define MUSE_INNATE_TPT 9999
  224.  * We cannot use this.  Since monsters get unlimited teleportation, if they
  225.  * were allowed to teleport at will you could never catch them.  Instead,
  226.  * assume they only teleport at random times, despite the inconsistency that if
  227.  * you polymorph into one you teleport at will.
  228.  */
  229.  
  230. /* Select a defensive item/action for a monster.  Returns TRUE iff one is
  231.  * found.
  232.  */
  233. boolean
  234. find_defensive(mtmp)
  235. struct monst *mtmp;
  236. {
  237.     register struct obj *obj;
  238.     struct trap *t;
  239.     int x=mtmp->mx, y=mtmp->my;
  240.     boolean stuck = (mtmp == u.ustuck);
  241.     boolean immobile = (mtmp->data->mmove == 0);
  242.  
  243.     if (mtmp->mpeaceful || is_animal(mtmp->data) || mindless(mtmp->data))
  244.         return 0;
  245.     if (u.uswallow && stuck) return 0;
  246.     if(dist2(x, y, mtmp->mux, mtmp->muy) > 25)
  247.         return 0;
  248.     if(mtmp->mhp >= mtmp->mhpmax ||
  249.             (mtmp->mhp >= 10 && mtmp->mhp*5 >= mtmp->mhpmax))
  250.         return 0;
  251.  
  252.     m.defensive = (struct obj *)0;
  253.     m.has_defense = 0;
  254.  
  255.     if (levl[x][y].typ == STAIRS && !stuck && !immobile) {
  256.         if (x == xdnstair && y == ydnstair)
  257.             m.has_defense = MUSE_DOWNSTAIRS;
  258.         if (x == xupstair && y == yupstair && ledger_no(&u.uz) != 1)
  259.     /* Unfair to let the monsters leave the dungeon with the Amulet */
  260.     /* (or go to the endlevel since you also need it, to get there) */
  261.             m.has_defense = MUSE_UPSTAIRS;
  262.     } else if (levl[x][y].typ == LADDER && !stuck && !immobile) {
  263.         if (x == xupladder && y == yupladder)
  264.             m.has_defense = MUSE_UP_LADDER;
  265.         if (x == xdnladder && y == ydnladder)
  266.             m.has_defense = MUSE_DN_LADDER;
  267.     } else if (sstairs.sx &&
  268.            sstairs.sx == mtmp->mx && sstairs.sy == mtmp->my) {
  269.         m.has_defense = MUSE_SSTAIRS;
  270.     } else if (!stuck && !immobile) {
  271.     /* Note: trapdoors take precedence over teleport traps. */
  272.         int xx, yy;
  273.  
  274.         for(xx = x-1; xx <= x+1; xx++) for(yy = y-1; yy <= y+1; yy++)
  275.         if (isok(xx,yy))
  276.         if (xx != u.ux && yy != u.uy)
  277.         if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y)
  278.         if ((xx==x && yy==y) || !level.monsters[xx][yy])
  279.         if ((t = t_at(xx,yy)) != 0) {
  280.             if (t->ttyp == TRAPDOOR
  281.                 && !is_floater(mtmp->data)
  282.                 && !mtmp->isshk && !mtmp->isgd
  283.                 && !mtmp->ispriest
  284.                 && Can_fall_thru(&u.uz)
  285.                         ) {
  286.                 trapx = xx;
  287.                 trapy = yy;
  288.                 m.has_defense = MUSE_TRAPDOOR;
  289.             } else if (t->ttyp == TELEP_TRAP && m.has_defense != MUSE_TRAPDOOR) {
  290.                 trapx = xx;
  291.                 trapy = yy;
  292.                 m.has_defense = MUSE_TELEPORT_TRAP;
  293.             }
  294.         }
  295.     }
  296.  
  297.     if (nohands(mtmp->data))    /* can't use objects */
  298.         goto botm;
  299.  
  300. #ifdef ARMY
  301.     if (is_mercenary(mtmp->data) && (obj = m_carrying(mtmp, BUGLE))) {
  302.         int xx, yy;
  303.         struct monst *mon;
  304.  
  305.         /* Distance is arbitrary.  What we really want to do is
  306.          * have the soldier play the bugle when it sees or
  307.          * remembers soldiers nearby...
  308.          */
  309.         for(xx = x-3; xx <= x+3; xx++) for(yy = y-3; yy <= y+3; yy++)
  310.         if (isok(xx,yy))
  311.         if ((mon = m_at(xx,yy)) && is_mercenary(mon->data) &&
  312.                 mon->data != &mons[PM_GUARD] &&
  313.                 (mon->msleep || (!mon->mcanmove))) {
  314.             m.defensive = obj;
  315.             m.has_defense = MUSE_BUGLE;
  316.         }
  317.     }
  318. #endif
  319.     if (m.has_defense == MUSE_UPSTAIRS ||
  320.             m.has_defense == MUSE_DOWNSTAIRS ||
  321.             m.has_defense == MUSE_UP_LADDER ||
  322.             m.has_defense == MUSE_DN_LADDER ||
  323.             m.has_defense == MUSE_SSTAIRS ||
  324. #ifdef ARMY
  325.             m.has_defense == MUSE_BUGLE ||
  326. #endif
  327.             m.has_defense == MUSE_TRAPDOOR)
  328.         goto botm;
  329. #define nomore(x) if(m.has_defense==x) continue;
  330.     for (obj = mtmp->minvent; obj; obj = obj->nobj) {
  331.         /* nomore(MUSE_WAN_DIGGING); */
  332.         if (m.has_defense == MUSE_WAN_DIGGING) break;
  333.         if (obj->otyp == WAN_DIGGING && obj->spe > 0 && !stuck
  334.             && !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
  335.             && !is_floater(mtmp->data)
  336. #ifdef MULDGN
  337.             && !Is_knox(&u.uz)
  338. #endif
  339.             && !In_endgame(&u.uz)) {
  340.             m.defensive = obj;
  341.             m.has_defense = MUSE_WAN_DIGGING;
  342.         }
  343.         nomore(MUSE_TELEPORT_TRAP);
  344.         nomore(MUSE_WAN_TELEPORTATION_SELF);
  345.         nomore(MUSE_WAN_TELEPORTATION);
  346.         if(obj->otyp == WAN_TELEPORTATION && obj->spe > 0) {
  347.             m.defensive = obj;
  348.             m.has_defense = (mon_has_amulet(mtmp))
  349.                 ? MUSE_WAN_TELEPORTATION
  350.                 : MUSE_WAN_TELEPORTATION_SELF;
  351.         }
  352.         nomore(MUSE_SCR_TELEPORTATION);
  353.         if(obj->otyp == SCR_TELEPORTATION && mtmp->mcansee
  354.            && haseyes(mtmp->data)
  355.            && (!obj->cursed ||
  356.                (!mtmp->isshk && !mtmp->isgd && !mtmp->ispriest))) {
  357.             m.defensive = obj;
  358.             m.has_defense = MUSE_SCR_TELEPORTATION;
  359.         }
  360.         nomore(MUSE_POT_EXTRA_HEALING);
  361.         if(obj->otyp == POT_EXTRA_HEALING) {
  362.             m.defensive = obj;
  363.             m.has_defense = MUSE_POT_EXTRA_HEALING;
  364.         }
  365.         nomore(MUSE_WAN_CREATE_MONSTER);
  366.         if(obj->otyp == WAN_CREATE_MONSTER && obj->spe > 0) {
  367.             m.defensive = obj;
  368.             m.has_defense = MUSE_WAN_CREATE_MONSTER;
  369.         }
  370.         nomore(MUSE_POT_HEALING);
  371.         if(obj->otyp == POT_HEALING) {
  372.             m.defensive = obj;
  373.             m.has_defense = MUSE_POT_HEALING;
  374.         }
  375.         nomore(MUSE_SCR_CREATE_MONSTER);
  376.         if(obj->otyp == SCR_CREATE_MONSTER) {
  377.             m.defensive = obj;
  378.             m.has_defense = MUSE_SCR_CREATE_MONSTER;
  379.         }
  380.     }
  381. botm:    return !!m.has_defense;
  382. #undef nomore
  383. }
  384.  
  385. /* Perform a defensive action for a monster.  Must be called immediately
  386.  * after find_defensive().  Return values are 0: did something, 1: died,
  387.  * 2: did something and can't attack again (i.e. teleported).
  388.  */
  389. int
  390. use_defensive(mtmp)
  391. struct monst *mtmp;
  392. {
  393.     int i;
  394.     struct obj *otmp = m.defensive;
  395.     boolean vis = cansee(mtmp->mx, mtmp->my);
  396.     boolean vismon = canseemon(mtmp);
  397.     boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
  398.  
  399.     if ((i = precheck(mtmp, otmp)) != 0) return i;
  400.     switch(m.has_defense) {
  401. #ifdef ARMY
  402.     case MUSE_BUGLE:
  403.         if (canseemon(mtmp))
  404.             pline("%s plays %s!", Monnam(mtmp), doname(otmp));
  405.         else if (flags.soundok)
  406.             You("hear the sound of a bugle!");
  407.         awaken_soldiers();
  408.         return 2;
  409. #endif
  410.     case MUSE_WAN_TELEPORTATION_SELF:
  411.         mzapmsg(mtmp, otmp, TRUE);
  412.         otmp->spe--;
  413.         if (oseen) makeknown(WAN_TELEPORTATION);
  414. mon_tele:
  415.         if(level.flags.noteleport) {
  416.             if (vismon)
  417.               pline("A mysterious force prevents %s from teleporting!",
  418.             mon_nam(mtmp));
  419.             return 2;
  420.         }
  421.         if((/*mon_has_amulet(mtmp)||*/ Is_wiz1_level(&u.uz) ||
  422.               Is_wiz2_level(&u.uz) || Is_wiz3_level(&u.uz))
  423.                                 && !rn2(3)) {
  424.             if (vismon)
  425.             pline("%s seems disoriented for a moment.",
  426.                 Monnam(mtmp));
  427.             return 2;
  428.         }
  429.         rloc(mtmp);
  430.         return 2;
  431.     case MUSE_WAN_TELEPORTATION:
  432.         zap_oseen = oseen;
  433.         mzapmsg(mtmp, otmp, FALSE);
  434.         otmp->spe--;
  435.         m_using = TRUE;
  436.         mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
  437.         m_using = FALSE;
  438.         return 2;
  439.     case MUSE_SCR_TELEPORTATION:
  440.         {
  441.         int obj_is_cursed = otmp->cursed;
  442.  
  443.         mreadmsg(mtmp, otmp);
  444.         m_useup(mtmp, otmp);    /* otmp might be free'ed */
  445.         if (oseen) makeknown(SCR_TELEPORTATION);
  446.         if (obj_is_cursed) {
  447.             if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
  448.                 if (vismon)
  449.                 pline("%s seems very disoriented for a moment.",
  450.                     Monnam(mtmp));
  451.                 return 2;
  452.             }
  453.             if (Is_botlevel(&u.uz)) goto mon_tele;
  454.             else {
  455.                 int nlev;
  456.                 d_level flev;
  457.  
  458.                 if (rn2(5)) nlev = rnd((int)depth(&u.uz) + 3);
  459.                 else {
  460.                 pline("%s shudders for a moment.",
  461.                             Monnam(mtmp));
  462.                 return 2; 
  463.                 }
  464.                 if (nlev == depth(&u.uz)) {
  465.                 if (u.uz.dlevel == 1) nlev++;
  466.                 else if (In_hell(&u.uz)) nlev--;
  467.                 else nlev++;
  468.                 }
  469.                 get_level(&flev, nlev);
  470.                 migrate_to_level(mtmp, ledger_no(&flev), 0);
  471.             }
  472.         } else goto mon_tele;
  473.         return 2;
  474.         }
  475.     case MUSE_WAN_DIGGING:
  476.         mzapmsg(mtmp, otmp, FALSE);
  477.         otmp->spe--;
  478.         if (oseen) makeknown(WAN_DIGGING);
  479.         if(IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ)
  480.            || (sstairs.sx && sstairs.sx == mtmp->mx &&
  481.                 sstairs.sy == mtmp->my)) {
  482.             pline("The digging ray is ineffective.");
  483.             return 2;
  484.         }
  485.         if (!Can_dig_down(&u.uz)) {
  486.             if(canseemon(mtmp))
  487.             pline("The floor here is too hard to dig in.");
  488.             return 2;
  489.         }
  490.         seetrap(maketrap(mtmp->mx, mtmp->my, TRAPDOOR));
  491.         if (vis) {
  492.             pline("%s's made a hole in the floor.", Monnam(mtmp));
  493.             pline("%s falls through...", Monnam(mtmp));
  494.         } else
  495. # ifdef SOUNDS
  496.             if (flags.soundok)
  497. # endif
  498.             You("hear something crash through the floor.");
  499.         /* we made sure that there is a level for mtmp to go to */
  500.         migrate_to_level(mtmp, ledger_no(&u.uz)+1, 0);
  501.         return 2;
  502.     case MUSE_WAN_CREATE_MONSTER:
  503.         {    coord cc;
  504.         struct permonst *pm=rndmonst();
  505.  
  506.         if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) return 0;
  507.         mzapmsg(mtmp, otmp, FALSE);
  508.         otmp->spe--;
  509.         if (oseen) makeknown(WAN_CREATE_MONSTER);
  510.         (void) makemon(pm, cc.x, cc.y);
  511.         return 2;
  512.         }
  513.     case MUSE_SCR_CREATE_MONSTER:
  514.         {    coord cc;
  515.         struct permonst *pm=rndmonst();
  516.         int cnt = 1;
  517.  
  518.         if (!rn2(73)) cnt += rnd(4);
  519.         if (mtmp->mconf || otmp->cursed) cnt += 12;
  520.         mreadmsg(mtmp, otmp);
  521.         while(cnt--) {
  522.             struct monst *mon;
  523.  
  524.             if (!enexto(&cc, mtmp->mx, mtmp->my, pm)) continue;
  525.             mon = makemon(mtmp->mconf ? &mons[PM_ACID_BLOB]
  526.                 : rndmonst(), cc.x, cc.y);
  527.             if (mon) newsym(mon->mx,mon->my);
  528.         }
  529.         if (oseen && !objects[SCR_CREATE_MONSTER].oc_name_known
  530.               && !objects[SCR_CREATE_MONSTER].oc_uname)
  531.             docall(otmp); /* not makeknown(); be consistent */
  532.         m_useup(mtmp, otmp);
  533.         return 2;
  534.         }
  535.     case MUSE_TRAPDOOR:
  536.         /* trapdoors on "bottom" levels of dungeons are rock-drop
  537.          * trapdoors, not holes in the floor.  We check here for
  538.          * safety.
  539.          */
  540.         if (Is_botlevel(&u.uz)) return 0;
  541.         if (vis) pline("%s %s into a trapdoor!", Monnam(mtmp),
  542.             makeplural(locomotion(mtmp->data, "jump")));
  543.         seetrap(t_at(trapx,trapy));
  544.  
  545.         /*  don't use rloc_to() because worm tails must "move" */
  546.         remove_monster(mtmp->mx, mtmp->my);
  547.         newsym(mtmp->mx, mtmp->my);    /* update old location */
  548.         place_monster(mtmp, trapx, trapy);
  549.         if (mtmp->wormno) worm_move(mtmp);
  550.         newsym(trapx, trapy);
  551.  
  552.         migrate_to_level(mtmp, ledger_no(&u.uz)+1, 0);
  553.         return 2;
  554.     case MUSE_UPSTAIRS:
  555.         /* Monsters without amulets escape the dungeon and are
  556.          * gone for good when they leave up the up stairs.
  557.          * Monsters with amulets would reach the endlevel,
  558.          * which we cannot allow since that would leave the
  559.          * player stranded.
  560.          */
  561.         if (ledger_no(&u.uz) == 1) {
  562.             if (mon_has_special(mtmp))
  563.                 return 0;
  564.             if (vismon) pline("%s escapes the dungeon!",
  565.                 Monnam(mtmp));
  566.             mongone(mtmp);
  567.             return 2;
  568.         }
  569.         if (vismon) pline("%s escapes upstairs!", Monnam(mtmp));
  570.         migrate_to_level(mtmp, ledger_no(&u.uz)-1, 2);
  571.         return 2;
  572.     case MUSE_DOWNSTAIRS:
  573.         if (vismon) pline("%s escapes downstairs!", Monnam(mtmp));
  574.         migrate_to_level(mtmp, ledger_no(&u.uz)+1, 1);
  575.         return 2;
  576.     case MUSE_UP_LADDER:
  577.         if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp));
  578.         migrate_to_level(mtmp, ledger_no(&u.uz)-1, 4);
  579.         return 2;
  580.     case MUSE_DN_LADDER:
  581.         if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp));
  582.         migrate_to_level(mtmp, ledger_no(&u.uz)+1, 3);
  583.         return 2;
  584.     case MUSE_SSTAIRS:
  585.         /* the stairs leading up from the 1st level are */
  586.         /* regular stairs, not sstairs.            */
  587.         if (sstairs.up) {
  588.             if (vismon)
  589.                 pline("%s escapes upstairs!", Monnam(mtmp));
  590.             if(Inhell) {
  591.                 migrate_to_level(mtmp,
  592.                      ledger_no(&sstairs.tolev), 0);
  593.                 return 2;
  594.             }
  595.         } else    if (vismon)
  596.             pline("%s escapes downstairs!", Monnam(mtmp));
  597.         migrate_to_level(mtmp, ledger_no(&sstairs.tolev), 5);
  598.         return 2;
  599.     case MUSE_TELEPORT_TRAP:
  600.         if (vis) pline("%s %s onto a teleport trap!", Monnam(mtmp),
  601.             makeplural(locomotion(mtmp->data, "jump")));
  602.         seetrap(t_at(trapx,trapy));
  603.  
  604.         /*  don't use rloc_to() because worm tails must "move" */
  605.         remove_monster(mtmp->mx, mtmp->my);
  606.         newsym(mtmp->mx, mtmp->my);    /* update old location */
  607.         place_monster(mtmp, trapx, trapy);
  608.         if (mtmp->wormno) worm_move(mtmp);
  609.         newsym(trapx, trapy);
  610.  
  611.         goto mon_tele;
  612.     case MUSE_POT_HEALING:
  613.         mquaffmsg(mtmp, otmp);
  614.         i = d(5,2) + 5 * !!bcsign(otmp);
  615.         mtmp->mhp += i;
  616.         if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = ++mtmp->mhpmax;
  617.         if (!otmp->cursed) mtmp->mcansee = 1;
  618.         if (vismon) pline("%s begins to look better.", Monnam(mtmp));
  619.         if (oseen) makeknown(POT_HEALING);
  620.         m_useup(mtmp, otmp);
  621.         return 2;
  622.     case MUSE_POT_EXTRA_HEALING:
  623.         mquaffmsg(mtmp, otmp);
  624.         i = d(5,4) + 5 * !!bcsign(otmp);
  625.         mtmp->mhp += i;
  626.         if (mtmp->mhp > mtmp->mhpmax)
  627.             mtmp->mhp = (mtmp->mhpmax += (otmp->blessed ? 5 : 2));
  628.         mtmp->mcansee = 1;
  629.         if (vismon) pline("%s looks much better.", Monnam(mtmp));
  630.         if (oseen) makeknown(POT_EXTRA_HEALING);
  631.         m_useup(mtmp, otmp);
  632.         return 2;
  633.     case 0: return 0; /* i.e. an exploded wand */
  634.     default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
  635.             m.has_defense);
  636.         break;
  637.     }
  638.     return 0;
  639. }
  640.  
  641. int
  642. rnd_defensive_item(mtmp)
  643. struct monst *mtmp;
  644. {
  645.     struct permonst *pm = mtmp->data;
  646.     int difficulty = monstr[(monsndx(pm))];
  647.  
  648.     if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
  649.             || pm->mlet == S_GHOST
  650. # ifdef KOPS
  651.             || pm->mlet == S_KOP
  652. # endif
  653.         ) return 0;
  654.     switch (rn2(8 + (difficulty > 3) + (difficulty > 6) +
  655.                 (difficulty > 8))) {
  656.         case 0: case 1:
  657.             return SCR_TELEPORTATION;
  658.         case 2: return SCR_CREATE_MONSTER;
  659.         case 3: case 4:
  660.             return POT_HEALING;
  661.         case 5: return POT_EXTRA_HEALING;
  662.         case 6: case 9:
  663.             return WAN_TELEPORTATION;
  664.         case 7: if (is_floater(pm) || mtmp->isshk || mtmp->isgd
  665.                         || mtmp->ispriest
  666.                                     )
  667.                 return 0;
  668.             else
  669.                 return WAN_DIGGING;
  670.         case 8: case 10:
  671.             return WAN_CREATE_MONSTER;
  672.     }
  673.     /*NOTREACHED*/
  674.     return 0;
  675. }
  676.  
  677. #define MUSE_WAN_DEATH 1
  678. #define MUSE_WAN_SLEEP 2
  679. #define MUSE_WAN_FIRE 3
  680. #define MUSE_WAN_COLD 4
  681. #define MUSE_WAN_LIGHTNING 5
  682. #define MUSE_WAN_MAGIC_MISSILE 6
  683. #define MUSE_WAN_STRIKING 7
  684. #define MUSE_SCR_FIRE 8
  685. #define MUSE_POT_PARALYSIS 9
  686. #define MUSE_POT_BLINDNESS 10
  687. #define MUSE_POT_CONFUSION 11
  688.  
  689. /* Select an offensive item/action for a monster.  Returns TRUE iff one is
  690.  * found.
  691.  */
  692. boolean
  693. find_offensive(mtmp)
  694. struct monst *mtmp;
  695. {
  696.     register struct obj *obj;
  697.     boolean ranged_stuff = lined_up(mtmp);
  698.  
  699.     m.offensive = (struct obj *)0;
  700.     m.has_offense = 0;
  701.     if (mtmp->mpeaceful || is_animal(mtmp->data) ||
  702.                 mindless(mtmp->data) || nohands(mtmp->data))
  703.         return 0;
  704.     if (u.uswallow) return 0;
  705.     if (in_your_sanctuary(mtmp->mx, mtmp->my)) return 0;
  706.  
  707.     if (!ranged_stuff) return 0;
  708. #define nomore(x) if(m.has_offense==x) continue;
  709.     for(obj=mtmp->minvent; obj; obj=obj->nobj) {
  710.         /* nomore(MUSE_WAN_DEATH); */
  711.         if (m.has_defense == WAN_DEATH) break;
  712.         if(obj->otyp == WAN_DEATH && obj->spe > 0) {
  713.             m.offensive = obj;
  714.             m.has_offense = MUSE_WAN_DEATH;
  715.         }
  716.         nomore(MUSE_WAN_SLEEP);
  717.         if(obj->otyp == WAN_SLEEP && obj->spe > 0 && multi >= 0) {
  718.             m.offensive = obj;
  719.             m.has_offense = MUSE_WAN_SLEEP;
  720.         }
  721.         nomore(MUSE_WAN_FIRE);
  722.         if(obj->otyp == WAN_FIRE && obj->spe > 0) {
  723.             m.offensive = obj;
  724.             m.has_offense = MUSE_WAN_FIRE;
  725.         }
  726.         nomore(MUSE_WAN_COLD);
  727.         if(obj->otyp == WAN_COLD && obj->spe > 0) {
  728.             m.offensive = obj;
  729.             m.has_offense = MUSE_WAN_COLD;
  730.         }
  731.         nomore(MUSE_WAN_LIGHTNING);
  732.         if(obj->otyp == WAN_LIGHTNING && obj->spe > 0) {
  733.             m.offensive = obj;
  734.             m.has_offense = MUSE_WAN_LIGHTNING;
  735.         }
  736.         nomore(MUSE_WAN_MAGIC_MISSILE);
  737.         if(obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) {
  738.             m.offensive = obj;
  739.             m.has_offense = MUSE_WAN_MAGIC_MISSILE;
  740.         }
  741.         nomore(MUSE_WAN_STRIKING);
  742.         if(obj->otyp == WAN_STRIKING && obj->spe > 0) {
  743.             m.offensive = obj;
  744.             m.has_offense = MUSE_WAN_STRIKING;
  745.         }
  746.         nomore(MUSE_POT_PARALYSIS);
  747.         if(obj->otyp == POT_PARALYSIS && multi >= 0) {
  748.             m.offensive = obj;
  749.             m.has_offense = MUSE_POT_PARALYSIS;
  750.         }
  751.         nomore(MUSE_POT_BLINDNESS);
  752.         if(obj->otyp == POT_BLINDNESS) {
  753.             m.offensive = obj;
  754.             m.has_offense = MUSE_POT_BLINDNESS;
  755.         }
  756.         nomore(MUSE_POT_CONFUSION);
  757.         if(obj->otyp == POT_CONFUSION) {
  758.             m.offensive = obj;
  759.             m.has_offense = MUSE_POT_CONFUSION;
  760.         }
  761. #if 0
  762.         nomore(MUSE_SCR_FIRE);
  763.         /* even more restrictive than ranged_stuff */
  764.         if(obj->otyp == SCR_FIRE && resists_fire(mtmp->data)
  765.            && distu(mtmp->mx,mtmp->my)==1
  766.            && mtmp->mcansee && haseyes(mtmp->data)) {
  767.             m.offensive = obj;
  768.             m.has_offense = MUSE_SCR_FIRE;
  769.         }
  770. #endif
  771.     }
  772.     return !!m.has_offense;
  773. #undef nomore
  774. }
  775.  
  776. static int
  777. mbhitm(mtmp, otmp)
  778. register struct monst *mtmp;
  779. register struct obj *otmp;
  780. {
  781.     int tmp;
  782.  
  783.     if (mtmp != &youmonst) {
  784.         mtmp->msleep = 0;
  785.         if (mtmp->m_ap_type) seemimic(mtmp);
  786.     }
  787.     switch(otmp->otyp) {
  788.     case WAN_STRIKING:
  789.         if (mtmp == &youmonst) {
  790.             if (zap_oseen) makeknown(WAN_STRIKING);
  791.             if (rnd(20) < 10 + u.uac) {
  792.                 pline("The wand hits you!");
  793.                 tmp = d(2,12);
  794.                 if(Half_spell_damage) tmp = (tmp+1) / 2;
  795.                 losehp(tmp, "wand", KILLED_BY_AN);
  796.             } else pline("The wand misses you.");
  797.             stop_occupation();
  798.             nomul(0);
  799.         } else if (rnd(20) < 10+find_mac(mtmp)) {
  800.             tmp = d(2,12);
  801.             if(Half_spell_damage) tmp = (tmp+1) / 2;
  802.             hit("wand", mtmp, exclam(tmp));
  803.             (void) resist(mtmp, otmp->oclass, tmp, TELL);
  804.             if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
  805.                 makeknown(WAN_STRIKING);
  806.         } else {
  807.             miss("wand", mtmp);
  808.             if (cansee(mtmp->mx, mtmp->my) && zap_oseen)
  809.                 makeknown(WAN_STRIKING);
  810.         }
  811.         break;
  812.     case WAN_TELEPORTATION:
  813.         if (mtmp == &youmonst) {
  814.             if (zap_oseen) makeknown(WAN_TELEPORTATION);
  815.             tele();
  816.         } else {
  817.             /* for consistency with zap.c, don't identify */
  818.             if (mtmp->ispriest &&
  819.                 *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
  820.                 if (cansee(mtmp->mx, mtmp->my))
  821.                 pline("%s resists the magic!", Monnam(mtmp));
  822.                 mtmp->msleep = 0;
  823.                 if(mtmp->m_ap_type) seemimic(mtmp);
  824.             } else
  825.                 rloc(mtmp);
  826.         }
  827.         break;
  828.     case WAN_CANCELLATION:
  829.     case SPE_CANCELLATION:
  830.         cancel_monst(mtmp, otmp, FALSE, TRUE, FALSE);
  831.         break;
  832.     }
  833.     return 0;
  834. }
  835.  
  836. /* A modified bhit() for monsters.  Based on bhit() in zap.c.  Unlike
  837.  * buzz(), bhit() doesn't take into account the possibility of a monster
  838.  * zapping you, so we need a special function for it.  (Unless someone wants
  839.  * to merge the two functions...)
  840.  */
  841. static void
  842. mbhit(mon,range,fhitm,fhito,obj)
  843. struct monst *mon;            /* monster shooting the wand */
  844. register int range;            /* direction and range */
  845. int FDECL((*fhitm),(MONST_P,OBJ_P));
  846. int FDECL((*fhito),(OBJ_P,OBJ_P));    /* fns called when mon/obj hit */
  847. struct obj *obj;            /* 2nd arg to fhitm/fhito */
  848. {
  849.     register struct monst *mtmp;
  850.     register struct obj *otmp;
  851.     register uchar typ;
  852.     int ddx, ddy;
  853.  
  854.     bhitpos.x = mon->mx;
  855.     bhitpos.y = mon->my;
  856.     ddx = sgn(mon->mux - mon->mx);
  857.     ddy = sgn(mon->muy - mon->my);
  858.  
  859.     while(range-- > 0) {
  860.         int x,y;
  861.  
  862.         bhitpos.x += ddx;
  863.         bhitpos.y += ddy;
  864.         x = bhitpos.x; y = bhitpos.y;
  865.         if (find_drawbridge(&x,&y))
  866.             switch (obj->otyp) {
  867.             case WAN_STRIKING:
  868.                 destroy_drawbridge(x,y);
  869.             }
  870.         if(bhitpos.x==u.ux && bhitpos.y==u.uy) {
  871.             (*fhitm)(&youmonst, obj);
  872.             range -= 3;
  873.         } else if(MON_AT(bhitpos.x, bhitpos.y)){
  874.             mtmp = m_at(bhitpos.x,bhitpos.y);
  875.             (*fhitm)(mtmp, obj);
  876.             range -= 3;
  877.         }
  878.         /* modified by GAN to hit all objects */
  879.         if(fhito){
  880.             int hitanything = 0;
  881.             register struct obj *next_obj;
  882.  
  883.             for(otmp = level.objects[bhitpos.x][bhitpos.y];
  884.                             otmp; otmp = next_obj) {
  885.             /* Fix for polymorph bug, Tim Wright */
  886.             next_obj = otmp->nexthere;
  887.             hitanything += (*fhito)(otmp, obj);
  888.             }
  889.             if(hitanything)    range--;
  890.         }
  891.         typ = levl[bhitpos.x][bhitpos.y].typ;
  892.         if(IS_DOOR(typ) || typ == SDOOR) {
  893.             switch (obj->otyp) {
  894.             case WAN_STRIKING:
  895.                 if (doorlock(obj, bhitpos.x, bhitpos.y))
  896.                 makeknown(obj->otyp);
  897.                 break;
  898.             }
  899.         }
  900.         if(!ZAP_POS(typ) || (IS_DOOR(typ) &&
  901.            (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED)))
  902.           ) {
  903.             bhitpos.x -= ddx;
  904.             bhitpos.y -= ddy;
  905.             break;
  906.         }
  907.     }
  908. }
  909.  
  910. /* Perform an offensive action for a monster.  Must be called immediately
  911.  * after find_offensive().  Return values are same as use_defensive().
  912.  */
  913. int
  914. use_offensive(mtmp)
  915. struct monst *mtmp;
  916. {
  917.     int i;
  918.     struct obj *otmp = m.offensive;
  919.     boolean vis = cansee(mtmp->mx, mtmp->my);
  920.     boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
  921.  
  922.     if ((i = precheck(mtmp, otmp)) != 0) return i;
  923.     switch(m.has_offense) {
  924.     case MUSE_WAN_DEATH:
  925.     case MUSE_WAN_SLEEP:
  926.     case MUSE_WAN_FIRE:
  927.     case MUSE_WAN_COLD:
  928.     case MUSE_WAN_LIGHTNING:
  929.     case MUSE_WAN_MAGIC_MISSILE:
  930.         mzapmsg(mtmp, otmp, FALSE);
  931.         otmp->spe--;
  932.         if (oseen) makeknown(otmp->otyp);
  933.         m_using = TRUE;
  934.         buzz((int)(-30 - (otmp->otyp - WAN_MAGIC_MISSILE)),
  935.             (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6,
  936.             mtmp->mx, mtmp->my,
  937.             sgn(mtmp->mux-mtmp->mx), sgn(mtmp->muy-mtmp->my));
  938.         m_using = FALSE;
  939.         return (mtmp->mhp <= 0) ? 1 : 2;
  940.     case MUSE_WAN_TELEPORTATION:
  941.     case MUSE_WAN_STRIKING:
  942.         zap_oseen = oseen;
  943.         mzapmsg(mtmp, otmp, FALSE);
  944.         otmp->spe--;
  945.         m_using = TRUE;
  946.         mbhit(mtmp,rn1(8,6),mbhitm,bhito,otmp);
  947.         m_using = FALSE;
  948.         return 2;
  949. #if 0
  950.     case MUSE_SCR_FIRE:
  951.         mreadmsg(mtmp, otmp);
  952.         if (mtmp->mconf) {
  953.             if (vis)
  954.                 pline("Oh, what a pretty fire!");
  955.         } else {
  956.             struct monst *mtmp2;
  957.             int num;
  958.  
  959.             if (vis)
  960.                 pline("The scroll erupts in a tower of flame!");
  961.             shieldeff(mtmp->mx, mtmp->my);
  962.             pline("%s is uninjured.", Monnam(mtmp));
  963.             (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
  964.             (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
  965.             (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
  966.             num = (2*(rn1(3, 3) + 2 * bcsign(otmp)) + 1)/3;
  967.             if (Fire_resistance)
  968.                 You("are not affected.");
  969.             if (Half_spell_damage) num = (num+1) / 2;
  970.             else losehp(num, "scroll of fire", KILLED_BY_AN);
  971.             for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon) {
  972.                if(mtmp == mtmp2) continue;
  973.                if(dist2(mtmp2->mx,mtmp2->my,mtmp->mx,mtmp->my) < 3){
  974.                 if (resists_fire(mtmp2->data)) continue;
  975.                 mtmp2->mhp -= num;
  976.                 if(resists_cold(mtmp2->data))
  977.                     mtmp2->mhp -= 3*num;
  978.                 if(mtmp2->mhp < 1) {
  979.                     mondied(mtmp2);
  980.                     break;
  981.                 }
  982.                 }
  983.             }
  984.         }
  985.         return 2;
  986. #endif
  987.     case MUSE_POT_PARALYSIS:
  988.     case MUSE_POT_BLINDNESS:
  989.     case MUSE_POT_CONFUSION:
  990.         /* Note: this setting of dknown doesn't suffice.  A monster
  991.          * which is out of sight might throw and it hits something _in_
  992.          * sight, a problem not existing with wands because wand rays
  993.          * are not objects.  Also set dknown in mthrowu.c.
  994.          */
  995.         if (cansee(mtmp->mx, mtmp->my)) {
  996.             otmp->dknown = 1;
  997.             pline("%s hurls %s!", Monnam(mtmp),
  998.                         singular(otmp, doname));
  999.         }
  1000.         m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux-mtmp->mx),
  1001.             sgn(mtmp->muy-mtmp->my),
  1002.             distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp);
  1003.         return 2;
  1004.     case 0: return 0; /* i.e. an exploded wand */
  1005.     default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
  1006.             m.has_offense);
  1007.         break;
  1008.     }
  1009.     return 0;
  1010. }
  1011.  
  1012. int
  1013. rnd_offensive_item(mtmp)
  1014. struct monst *mtmp;
  1015. {
  1016.     struct permonst *pm = mtmp->data;
  1017.     int difficulty = monstr[(monsndx(pm))];
  1018.  
  1019.     if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
  1020.             || pm->mlet == S_GHOST
  1021. # ifdef KOPS
  1022.             || pm->mlet == S_KOP
  1023. # endif
  1024.         ) return 0;
  1025.     if (difficulty > 7 && !rn2(35)) return WAN_DEATH;
  1026.     switch (rn2(7 - (difficulty < 4) + 4 * (difficulty > 6))) {
  1027.         case 0: case 1:
  1028.             return WAN_STRIKING;
  1029.         case 2: return POT_CONFUSION;
  1030.         case 3: return POT_BLINDNESS;
  1031.         case 4: return POT_PARALYSIS;
  1032.         case 5: case 6:
  1033.             return WAN_MAGIC_MISSILE;
  1034.         case 7: return WAN_SLEEP;
  1035.         case 8: return WAN_FIRE;
  1036.         case 9: return WAN_COLD;
  1037.         case 10: return WAN_LIGHTNING;
  1038.     }
  1039.     /*NOTREACHED*/
  1040.     return 0;
  1041. }
  1042.  
  1043. #define MUSE_POT_GAIN_LEVEL 1
  1044. #define MUSE_WAN_MAKE_INVISIBLE 2
  1045. #define MUSE_POT_INVISIBILITY 3
  1046. #define MUSE_POLY_TRAP 4
  1047. #define MUSE_WAN_POLYMORPH 5
  1048. #define MUSE_POT_SPEED 6
  1049. #define MUSE_WAN_SPEED_MONSTER 7
  1050. boolean
  1051. find_misc(mtmp)
  1052. struct monst *mtmp;
  1053. {
  1054.     register struct obj *obj;
  1055.     int x=mtmp->mx, y=mtmp->my;
  1056. #ifdef POLYSELF
  1057.     struct trap *t;
  1058.     int xx, yy;
  1059.     boolean immobile = (mtmp->data->mmove == 0);
  1060. #endif
  1061.     boolean stuck = (mtmp == u.ustuck);
  1062.  
  1063.     m.misc = (struct obj *)0;
  1064.     m.has_misc = 0;
  1065.     if (is_animal(mtmp->data) || mindless(mtmp->data))
  1066.         return 0;
  1067.     if (u.uswallow && stuck) return 0;
  1068.  
  1069.     /* We arbitrarily limit to times when a player is nearby for the
  1070.      * same reason as Junior Pac-Man doesn't have energizers eaten until
  1071.      * you can see them...
  1072.      */
  1073.     if(dist2(x, y, mtmp->mux, mtmp->muy) > 36)
  1074.         return 0;
  1075.  
  1076. #ifdef POLYSELF
  1077.     if (!stuck && !immobile &&
  1078.             !mtmp->cham && monstr[(monsndx(mtmp->data))] < 6)
  1079.       for(xx = x-1; xx <= x+1; xx++)
  1080.         for(yy = y-1; yy <= y+1; yy++)
  1081.         if (isok(xx,yy) && (xx != u.ux || yy != u.uy))
  1082.             if (mtmp->data != &mons[PM_GRID_BUG] || xx == x || yy == y)
  1083.             if (/* (xx==x && yy==y) || */ !level.monsters[xx][yy])
  1084.                 if ((t = t_at(xx,yy)) != 0) {
  1085.                 if (t->ttyp == POLY_TRAP) {
  1086.                     trapx = xx;
  1087.                     trapy = yy;
  1088.                     m.has_misc = MUSE_POLY_TRAP;
  1089.                     return TRUE;
  1090.                 }
  1091.                 }
  1092. #endif
  1093.     if (nohands(mtmp->data))
  1094.         return 0;
  1095.  
  1096. #define nomore(x) if(m.has_misc==x) continue;
  1097.     for(obj=mtmp->minvent; obj; obj=obj->nobj) {
  1098.         /* Monsters shouldn't recognize cursed items; this kludge is */
  1099.         /* necessary to prevent serious problems though... */
  1100.         if(obj->otyp == POT_GAIN_LEVEL && (!obj->cursed ||
  1101.                 (!mtmp->isgd && !mtmp->isshk && !mtmp->ispriest))) {
  1102.             m.misc = obj;
  1103.             m.has_misc = MUSE_POT_GAIN_LEVEL;
  1104.         }
  1105.         /* Note: peaceful/tame monsters won't make themselves
  1106.          * invisible unless you can see them.  Not really right, but...
  1107.          */
  1108.         nomore(MUSE_WAN_MAKE_INVISIBLE);
  1109.         if(obj->otyp == WAN_MAKE_INVISIBLE && obj->spe > 0 &&
  1110.              !mtmp->minvis && (!mtmp->mpeaceful || See_invisible)
  1111.             && (mtmp->data != &mons[PM_MEDUSA] || mtmp->mcan)) {
  1112.             m.misc = obj;
  1113.             m.has_misc = MUSE_WAN_MAKE_INVISIBLE;
  1114.         }
  1115.         nomore(MUSE_POT_INVISIBILITY);
  1116.         if(obj->otyp == POT_INVISIBILITY &&
  1117.              !mtmp->minvis && (!mtmp->mpeaceful || See_invisible)) {
  1118.             m.misc = obj;
  1119.             m.has_misc = MUSE_POT_INVISIBILITY;
  1120.         }
  1121.         nomore(MUSE_WAN_SPEED_MONSTER);
  1122.         if(obj->otyp == WAN_SPEED_MONSTER && obj->spe > 0
  1123.                 && mtmp->mspeed != MFAST && !mtmp->isgd) {
  1124.             m.misc = obj;
  1125.             m.has_misc = MUSE_WAN_SPEED_MONSTER;
  1126.         }
  1127.         nomore(MUSE_POT_SPEED);
  1128.         if(obj->otyp == POT_SPEED && mtmp->mspeed != MFAST
  1129.                             && !mtmp->isgd) {
  1130.             m.misc = obj;
  1131.             m.has_misc = MUSE_POT_SPEED;
  1132.         }
  1133.         nomore(MUSE_WAN_POLYMORPH);
  1134.         if(obj->otyp == WAN_POLYMORPH && !mtmp->cham
  1135.                 && monstr[(monsndx(mtmp->data))] < 6) {
  1136.             m.misc = obj;
  1137.             m.has_misc = MUSE_WAN_POLYMORPH;
  1138.         }
  1139.     }
  1140.     return !!m.has_misc;
  1141. #undef nomore
  1142. }
  1143.  
  1144. int
  1145. use_misc(mtmp)
  1146. struct monst *mtmp;
  1147. {
  1148.     int i;
  1149.     struct obj *otmp = m.misc;
  1150.     boolean vis = cansee(mtmp->mx, mtmp->my);
  1151.     boolean vismon = canseemon(mtmp);
  1152.     boolean oseen = otmp && (otmp->oclass == SCROLL_CLASS || vis);
  1153.  
  1154.     if ((i = precheck(mtmp, otmp)) != 0) return i;
  1155.     switch(m.has_misc) {
  1156.     case MUSE_POT_GAIN_LEVEL:
  1157.         mquaffmsg(mtmp, otmp);
  1158.         if (otmp->cursed) {
  1159.             if (Can_rise_up(&u.uz)) {
  1160.             register int tolev = depth(&u.uz)-1;
  1161.             d_level tolevel;
  1162.  
  1163.             get_level(&tolevel, tolev);
  1164.             /* insurance against future changes... */
  1165.             if(on_level(&tolevel, &u.uz)) goto skipmsg;
  1166.             if (vismon) {
  1167.                 pline("%s rises up, through the ceiling!",
  1168.                 Monnam(mtmp));
  1169.                 if(!objects[POT_GAIN_LEVEL].oc_name_known
  1170.                   && !objects[POT_GAIN_LEVEL].oc_uname)
  1171.                 docall(otmp);
  1172.             }
  1173.             m_useup(mtmp, otmp);
  1174.             migrate_to_level(mtmp, ledger_no(&tolevel), 0);
  1175.             return 2;
  1176.             } else {
  1177. skipmsg:
  1178.             if (vismon) {
  1179.                 pline("%s looks uneasy.", Monnam(mtmp));
  1180.                 if(!objects[POT_GAIN_LEVEL].oc_name_known
  1181.                   && !objects[POT_GAIN_LEVEL].oc_uname)
  1182.                 docall(otmp);
  1183.             }
  1184.             m_useup(mtmp, otmp);
  1185.             return 2;
  1186.             }
  1187.         }
  1188.         if (vismon) pline("%s seems more experienced.", Monnam(mtmp));
  1189.         i = rnd(8);
  1190.         if (oseen) makeknown(POT_GAIN_LEVEL);
  1191.         m_useup(mtmp, otmp);
  1192.         if (!grow_up(mtmp,(struct monst *)0)) return 1;
  1193.             /* grew into genocided monster */
  1194.         mtmp->mhp += i;
  1195.         mtmp->mhpmax += i;
  1196.         return 2;
  1197.     case MUSE_WAN_MAKE_INVISIBLE:
  1198.         mzapmsg(mtmp, otmp, TRUE);
  1199.         otmp->spe--;
  1200.         mtmp->minvis = 1;
  1201.         newsym(mtmp->mx,mtmp->my);
  1202.         if (mtmp->wormno) see_wsegs(mtmp);
  1203.         return 2;
  1204.     case MUSE_POT_INVISIBILITY:
  1205.         mquaffmsg(mtmp, otmp);
  1206.         if (vis) pline("Gee, all of a sudden %s can't see %sself.",
  1207.             mon_nam(mtmp),
  1208.             humanoid(mtmp->data) ? (mtmp->female ? "her" : "him")
  1209.                          : "it");
  1210.         if (oseen) makeknown(POT_INVISIBILITY);
  1211.         mtmp->minvis = 1;
  1212.         newsym(mtmp->mx,mtmp->my);
  1213.         if (mtmp->wormno) see_wsegs(mtmp);
  1214.         if (otmp->cursed) {
  1215.             mtmp->minvis = 0;
  1216.             pline("For some reason, %s presence is known to you.",
  1217.                 s_suffix(mon_nam(mtmp)));
  1218.             you_aggravate(mtmp);
  1219.             mtmp->minvis = 1;
  1220.             newsym(mtmp->mx,mtmp->my);
  1221.         }
  1222.         m_useup(mtmp, otmp);
  1223.         return 2;
  1224.     case MUSE_WAN_SPEED_MONSTER:
  1225.         mzapmsg(mtmp, otmp, TRUE);
  1226.         otmp->spe--;
  1227.         if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
  1228.         else mtmp->mspeed = MFAST;
  1229.         return 2;
  1230.     case MUSE_POT_SPEED:
  1231.         mquaffmsg(mtmp, otmp);
  1232.         if (vismon) pline("%s is suddenly moving much faster.",
  1233.             Monnam(mtmp));
  1234.         if (oseen) makeknown(POT_SPEED);
  1235.         if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
  1236.         else mtmp->mspeed = MFAST;
  1237.         m_useup(mtmp, otmp);
  1238.         return 2;
  1239.     case MUSE_WAN_POLYMORPH:
  1240.         mzapmsg(mtmp, otmp, TRUE);
  1241.         otmp->spe--;
  1242.         (void) newcham(mtmp, rndmonst());
  1243.         if (oseen) makeknown(WAN_POLYMORPH);
  1244.         return 2;
  1245. #ifdef POLYSELF
  1246.     case MUSE_POLY_TRAP:
  1247.         if (vismon)
  1248.             pline("%s deliberately goes onto a polymorph trap!",
  1249.               Monnam(mtmp));
  1250.         seetrap(t_at(trapx,trapy));
  1251.  
  1252.         /*  don't use rloc() due to worms */
  1253.         remove_monster(mtmp->mx, mtmp->my);
  1254.         newsym(mtmp->mx, mtmp->my);
  1255.         place_monster(mtmp, trapx, trapy);
  1256.         if (mtmp->wormno) worm_move(mtmp);
  1257.         newsym(trapx, trapy);
  1258.  
  1259.         (void) newcham(mtmp, (struct permonst *)0);
  1260.         return 2;
  1261. #endif
  1262.     case 0: return 0; /* i.e. an exploded wand */
  1263.     default: impossible("%s wanted to perform action %d?", Monnam(mtmp),
  1264.             m.has_misc);
  1265.         break;
  1266.     }
  1267.     return 0;
  1268. }
  1269.  
  1270. static void
  1271. you_aggravate(mtmp)
  1272. struct monst *mtmp;
  1273. {
  1274.     cls();
  1275.     show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp));
  1276.     display_self();
  1277.     You("feel aggravated at %s.", mon_nam(mtmp));
  1278.     display_nhwindow(WIN_MAP, TRUE);
  1279.     docrt();
  1280.     if (unconscious()) {
  1281.         multi = -1;
  1282.         nomovemsg =
  1283.               "Aggravated, you are jolted into full consciousness.";
  1284.     }
  1285. }
  1286.  
  1287. int
  1288. rnd_misc_item(mtmp)
  1289. struct monst *mtmp;
  1290. {
  1291.     struct permonst *pm = mtmp->data;
  1292.     int difficulty = monstr[(monsndx(pm))];
  1293.  
  1294.     if(is_animal(pm) || attacktype(pm, AT_EXPL) || mindless(mtmp->data)
  1295.             || pm->mlet == S_GHOST
  1296. # ifdef KOPS
  1297.             || pm->mlet == S_KOP
  1298. # endif
  1299.         ) return 0;
  1300.     /* Unlike other rnd_item functions, we only allow _weak_ monsters
  1301.      * to have this item; after all, the item will be used to strengthen
  1302.      * the monster and strong monsters won't use it at all...
  1303.      */
  1304.     if (difficulty < 6 && !rn2(30)) return WAN_POLYMORPH;
  1305.  
  1306.     switch (rn2(7)) {
  1307.         case 0: case 1:
  1308.             if (mtmp->isgd) return 0;
  1309.             return POT_SPEED;
  1310.         case 2:
  1311.             if (mtmp->mpeaceful && !See_invisible) return 0;
  1312.             return WAN_MAKE_INVISIBLE;
  1313.         case 3:
  1314.             if (mtmp->mpeaceful && !See_invisible) return 0;
  1315.             return POT_INVISIBILITY;
  1316.         case 4:
  1317.             if (mtmp->isgd) return 0;
  1318.             return WAN_SPEED_MONSTER;
  1319.         case 5: case 6:
  1320.             return POT_GAIN_LEVEL;
  1321.     }
  1322.     /*NOTREACHED*/
  1323.     return 0;
  1324. }
  1325.  
  1326. boolean
  1327. searches_for_item(mon, obj)
  1328. struct monst *mon;
  1329. struct obj *obj;
  1330. {
  1331.     int typ = obj->otyp;
  1332.  
  1333.     if (is_animal(mon->data) || mindless(mon->data)) return FALSE;
  1334.     return((obj->oclass == WAND_CLASS && objects[typ].oc_dir == RAY)
  1335.         || typ == WAN_STRIKING
  1336.         || (!mon->minvis &&
  1337.             (typ == WAN_MAKE_INVISIBLE || typ == POT_INVISIBILITY))
  1338.         || (mon->mspeed != MFAST &&
  1339.             (typ == WAN_SPEED_MONSTER || typ == POT_SPEED))
  1340.         || typ == POT_HEALING
  1341.         || typ == POT_EXTRA_HEALING
  1342.         || typ == POT_GAIN_LEVEL
  1343.         || (monstr[monsndx(mon->data)] < 6 && typ == WAN_POLYMORPH)
  1344.         || (!is_floater(mon->data) && typ == WAN_DIGGING)
  1345.         || typ == WAN_TELEPORTATION
  1346.         || typ == SCR_TELEPORTATION
  1347.         || typ == WAN_CREATE_MONSTER
  1348.         || typ == SCR_CREATE_MONSTER
  1349.         || typ == POT_PARALYSIS
  1350.         || typ == POT_BLINDNESS
  1351.         || typ == POT_CONFUSION
  1352.         || (typ == PICK_AXE && needspick(mon->data))
  1353.     );
  1354. }
  1355. #endif
  1356.  
  1357. /*muse.c*/
  1358.